import React, { useEffect, useRef, useState } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import ImageScrollbar from '../ImageScrollbar/ImageScrollbar.js';
import ImageViewport from '../ImageViewport/ImageViewport.js';

import './CornerstoneViewport.css';

function CornerstoneViewport(props) {
  const {
    className,
    style,
    numRows,
    numColumns,
    activeImageViewportIndex,
    imageIds,
  } = props;
  const gridEle = useRef(null);
  const [cells, setCells] = useState(1);
  const [context, setContext] = useState(null);
  const [scrollIndex, setScrollIndex] = useState(0);
  const [scrollbarMax, setScrollbarMax] = useState(0);
  const [viewports, setViewports] = useState([]);

  const imageSliderOnInputCallback = value => {
    setScrollIndex(value);
  };

  const onNewImage = ({ imageViewportIndex, currentImageIdIndex }) => {
    if (
      imageViewportIndex === activeImageViewportIndex &&
      currentImageIdIndex >= 0
    ) {
      setScrollIndex(currentImageIdIndex / cells);
    }
  };

  useEffect(() => {
    setScrollbarMax(Math.ceil(imageIds.length / cells) - 1);
  }, [imageIds, cells]);

  useEffect(() => {
    setContext(null);
    setScrollIndex(0);
  }, [imageIds]);

  useEffect(() => {
    if (scrollbarMax < scrollIndex) {
      setScrollIndex(0);
    }
  }, [scrollbarMax, scrollIndex]);

  useEffect(() => {
    setCells(numRows * numColumns);
  }, [numColumns, numRows]);

  const onContextChanged = context => {
    setContext({ ...context });
  };

  const onDoubleClick = () => {
    if (props.onDoubleClick) {
      props.onDoubleClick(props.viewportIndex);
    }
  };

  useEffect(() => {
    const updatedViewports = [];
    const start = scrollIndex * cells;

    for (let i = 0; i < cells && i + start < imageIds.length; i++) {
      updatedViewports.push(
        <ImageViewport
          key={`image-viewport-${i}`}
          {...props}
          imageIdIndex={i + start}
          onContextChanged={onContextChanged}
          onDoubleClick={onDoubleClick}
          context={context}
          imageViewportIndex={i}
          onNewImage={onNewImage}
        />
      );
    }

    setViewports(updatedViewports);
  }, [props, scrollIndex, context, cells]);

  const scrollbarHeight = gridEle.current
    ? `${gridEle.current.clientHeight - 20}px`
    : '100px';

  return (
    <div style={style} className={classNames('viewport-wrapper', className)}>
      <div
        style={{
          display: 'grid',
          gridTemplateRows: `repeat(${numRows}, ${100.0 / numRows}%)`,
          gridTemplateColumns: `repeat(${numColumns}, ${100.0 / numColumns}%)`,
          height: '100%',
          width: '100%',
        }}
        ref={gridEle}
      >
        {viewports}
      </div>
      <ImageScrollbar
        onInputCallback={imageSliderOnInputCallback}
        max={scrollbarMax}
        height={scrollbarHeight}
        value={scrollIndex}
      />
      {props.children}
    </div>
  );
}

CornerstoneViewport.propTypes = {
  viewportIndex: PropTypes.number.isRequired,
  imageIds: PropTypes.arrayOf(PropTypes.string).isRequired,
  imageIdIndex: PropTypes.number,

  setViewportActive: PropTypes.func, // Called when viewport should be set to active?
  onNewImage: PropTypes.func,
  useSynchronizerContext: PropTypes.func,
  onDoubleClick: PropTypes.func,

  numRows: PropTypes.number,
  numColumns: PropTypes.number,
  className: PropTypes.string,
  style: PropTypes.object,
  activeImageViewportIndex: PropTypes.number,
  children: PropTypes.node,
};

CornerstoneViewport.defaultProps = {
  imageIds: [],
  imageIdIndex: 0,
  numRows: 1,
  numColumns: 1,
};

export default CornerstoneViewport;
